package com.ocm.mq.aspect;


import com.alibaba.fastjson.JSON;
import com.ocm.mq.entity.MqError;
import com.ocm.mq.service.IMqErrorService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.amqp.core.Message;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;

/**
 * @Author hqy
 * @Date 23/01/2022
 * @Description
 */
@Aspect
@Slf4j
@Component
public class MQAspect {

	@Resource
	private IMqErrorService mqErrorService;
	/**
	 * 切方法@RabbitAutoAck 注解
	 */
	@Around("@annotation(com.ocm.mq.annotation.RabbitAutoAck)")
	public Object RabbitAutoAck(ProceedingJoinPoint point) {
		Object[] args = point.getArgs();
		Channel channel =null;
		Message message =null;
		Object o=null;
		for (Object arg : args) {
			if (arg instanceof Channel) {
				channel= (Channel) arg;
			}else if(arg instanceof Message){
				message=(Message) arg;
			}
		}
		if(channel==null||message==null){
			throw new RuntimeException("队列参数获取失败");
		}
		try {
			Long deliveryTag = message.getMessageProperties().getDeliveryTag();
			if(deliveryTag.equals(10L)){
				log.error("mq重试次数达到限制,拒绝重试并记录本次数据");
				mqErrorService.save(new MqError(JSON.toJSONString(message),new Date()));
				channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
			}
			o=point.proceed();
			//ack此信息
			channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
			return o;
		} catch (Throwable e){
			e.printStackTrace();
			try {
				channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
		return o;

	}

}
